package icu.zhangzihan.gis251.controller;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/api/ai")
public class AIController {

    private static final String DEEPSEEK_URL = "https://api.deepseek.com/v1/chat/completions";
    private static final String API_KEY = "sk-66f62a9fecde4116a7037f1ba3a1361f";

    @GetMapping(value = "/ask", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter askQuestion(@RequestParam String question,
                                  HttpServletRequest httpRequest) {


        SseEmitter emitter = new SseEmitter(60_000L);

        Executors.newSingleThreadExecutor().submit(() -> {
            try {
                RestTemplate restTemplate = new RestTemplate();

                // 构建请求头
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.set("Authorization", "Bearer " + API_KEY);

                // 构建请求体
                Map<String, Object> body = new HashMap<>();
                body.put("model", "deepseek-chat");
                body.put("stream", true);

                List<Map<String, String>> messages = new ArrayList<>();
                messages.add(createSystemMessage());
                messages.add(createUserMessage(question)); // 使用 URL 参数中的问题
                body.put("messages", messages);

                // 发送请求
                restTemplate.execute(DEEPSEEK_URL, HttpMethod.POST,
                        (RequestCallback) req -> {
                            headers.forEach(req.getHeaders()::addAll);
                            new ObjectMapper().writeValue(req.getBody(), body);
                        },
                        response -> processStream(response, emitter)
                );

            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });

        return emitter;
    }

    // 创建系统角色消息
    private Map<String, String> createSystemMessage() {
        return new HashMap<String, String>() {{
            put("role", "system");
            put("content", buildSystemPrompt());
        }};
    }

    // 创建用户消息
    private Map<String, String> createUserMessage(String question) {
        return new HashMap<String, String>() {{
            put("role", "user");
            put("content", question);
        }};
    }

    // 精简后的角色提示
    private String buildSystemPrompt() {
        return "你是专业烘焙助手，请根据以下规范回答用户问题：\n\n"
                + "【身份设定】\n"
                + "1. 资深厨师，擅长所有美食制作\n"
                + "2. 熟悉材料特性、工艺流程及问题排查\n\n"
                + "【回答范围】\n"
                + "1. 材料替代方案（如无低筋面粉时）\n"
                + "2. 烘焙步骤优化建议\n"
                + "3. 失败案例原因分析（塌陷、开裂等）\n"
                + "4. 工具使用技巧（烤箱温度校准等）\n"
                + "5. 食谱调整建议（湿度/温度/时间）\n"
                + "6. 营养搭配建议（低糖/低脂方案）\n\n"
                + "【回答要求】\n"
                + "1. 分步骤说明，重要技巧用★标注\n"
                + "2. 给出原理说明（如：蛋白打发程度影响）\n"
                + "3. 使用标准计量单位（克/毫升/华氏度）\n"
                + "4. 涉及安全操作时重点强调（如烤箱防烫）\n"
                + "5. 不确定时请说明'建议进行小批量测试'";
    }

    // 流式响应处理
    private Void processStream(ClientHttpResponse response, SseEmitter emitter) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("data: ")) {
                    String json = line.substring(6);
                    if ("[DONE]".equals(json)) break;

                    JsonNode node = new ObjectMapper().readTree(json);
                    String content = node.path("choices")
                            .get(0)
                            .path("delta")
                            .path("content")
                            .asText("");

                    emitter.send(SseEmitter.event()
                            .data(content)
                            .id(UUID.randomUUID().toString()));
                }
            }
            emitter.complete();
        } catch (IOException e) {
            emitter.completeWithError(e);
            throw e;
        }
        return null;
    }
}